package com.meng.thrift.server.thrift.util;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadedSelectorServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;


/**
 * Thrift 服务代理类 （工厂设计模式） 整合spring
 *
 * @author MENG
 * @version 2017/10/31
 * @see
 */
public class ThriftServerProxy implements Runnable
{

    private Logger logger = LoggerFactory.getLogger(ThriftServerProxy.class);

    private int serverPort;             //服务端口

    private String serverInterface;     //服务接口

    private Object serverInterfaceImpl; //服务接口的实现

    public String getServerInterface()
    {
        return serverInterface;
    }

    public int getServerPort()
    {
        return serverPort;
    }

    public void setServerPort(int serverPort)
    {
        this.serverPort = serverPort;
    }

    public void setServerInterface(String serverInterface)
    {
        this.serverInterface = serverInterface;
    }

    public Object getServerInterfaceImpl()
    {
        return serverInterfaceImpl;
    }

    public void setServerInterfaceImpl(Object serverInterfaceImpl)
    {
        this.serverInterfaceImpl = serverInterfaceImpl;
    }

    public ThriftServerProxy(int serverPort,String serverInterface,Object serverInterfaceImpl)
    {
        this.serverPort = serverPort;

        this.serverInterface = serverInterface;

        this.serverInterfaceImpl = serverInterfaceImpl;
    }

    @Override
    public void run()
    {
        try
        {
            // 非阻塞式的，配合TFramedTransport使用
            TNonblockingServerSocket tNonblockingServerSocket = new TNonblockingServerSocket(getServerPort());

            //通过反射 获取TProcessor 对象

            // ---------------------实现类处理类class
            //例如 TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(new HwServciceImpl());
            Class Processor = Class.forName(getServerInterface() + "$Processor");

            // 接口
            Class Iface = Class.forName(getServerInterface() + "$Iface");

            // 接口构造方法类
            Constructor con = Processor.getConstructor(Iface);

            // 实现类处理类
            TProcessor processor = (TProcessor) con.newInstance(getServerInterfaceImpl());
            // ---------------------

            // 目前Thrift提供的最高级的模式，可并发处理客户端请求
            TThreadedSelectorServer.Args args = new TThreadedSelectorServer.Args(tNonblockingServerSocket);

            args.processor(processor);

            // //  设置传输工厂，使用非阻塞方式，按块的大小进行传输，类似于Java中的NIO
            args.transportFactory(new TFramedTransport.Factory());

            //协议和客户端一致 二进制格式
            TBinaryProtocol.Factory protFactory = new TBinaryProtocol.Factory();

            args.protocolFactory(protFactory);
            //---------

            TServer server = new TThreadedSelectorServer(args);

            server.serve();//启动服务
        }
        catch (Exception e)
        {
            logger.error("启动Thrift Server出现错误",e);
        }

    }
}
